package server;

import java.io.*;
import java.net.*;

import maze.*;
import test.Main;

/**
 * @author Denis Toikka
 * Connection between server and client.
 */
public class Communications {

	/**
	 * Server socket.
	 */
	ServerSocket server;
	/**
	 * Socket, connect with client.
	 */
	Socket sock;
	
	/**
	 * Constructor.
	 */
	public Communications() {
		int port = 8888;
		try {
			server = new ServerSocket(port);
			Main.log.print("Server is ready for new player");
			this.sock = server.accept();
			Main.log.print("New player entered to the server");
		} catch (IOException e) {
			Main.log.print(e);
		}
	}

	/**
	 * @param game
	 * @throws IOException
	 * New client connected, create new player, start communication.
	 */
	public void setConnection(Game game) throws IOException {
		Player pl = Main.game.createNewPlayer();
		Client c = new Client(pl, game);
		c.start();
	}
	
	/**
	 * Close connection, prepare to new client.
	 */
	public void endConnection() {
		try {
			this.sock.close();
			this.server.close();
		} catch(Exception e) {
			Main.log.print(e);
		}
		Main.log.print("Player left the server");
		Main.game.endThisPart();
	}
}

/**
 * @author Denis Toikka
 * Conversation between client and game.
 */
class Client extends Thread {
	
	/**
	 * Current player.
	 */
	Player pl;
	/**
	 * Current game.
	 */
	Game game;
	
	/**
	 * @param pl
	 * @param game
	 * Constructor.
	 */
	Client(Player pl, Game game) {
		this.pl = pl;
		this.game = game;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	public void run() {
		try {
			BufferedReader	netIn = new BufferedReader(new InputStreamReader(
					Main.server.sock.getInputStream()));
			PrintWriter netOut = new PrintWriter(new BufferedWriter(
				new OutputStreamWriter(Main.server.sock.getOutputStream())), true);
			printInfo(netOut);
			clientConversation(netIn, netOut);
		} catch (Exception e) {
			Main.log.print(e);
		}
		Main.server.endConnection();
	}
	
	/**
	 * @param netIn
	 * @param netOut
	 * Check first commands. Prepare to main process.
	 */
	void clientConversation(BufferedReader	netIn, PrintWriter netOut) {
		String fromClient;
		while(!this.game.stopProgram) {
			String response = "";
			try {
				fromClient = netIn.readLine();
				String[] command = fromClient.split(" ");
				if(fromClient==null) {
					continue;
				}
				if("HELP".equalsIgnoreCase(fromClient)) {
					printHelp(netOut);
					continue;
				}
				else if("QUIT".equalsIgnoreCase(fromClient)) {
					break;
				}
				else if(this.pl.name == "") {
					response = "Please enter your name";
				}
				else{
					response = this.game.processCommand(fromClient, this.pl, netOut);
					if(response == "break") break;
				}
				if("NAME".equalsIgnoreCase(command[0])) {
					String name = "";
					for(int j = 1; j < command.length; j++){
						if(name == "") name += command[j];
						else name = name + " " + command[j];
					}
					this.pl.name = name;
					response = "Hello, " + name;
				}
				netOut.println(response + "\n");
			} catch(Exception e) {
				Main.log.print(e);
				break;
			}
		}
	}
	
	/**
	 * @param netOut
	 * Prints information about project.
	 */
	void printInfo(PrintWriter netOut) {
		netOut.println("Welcome to maze.net created by Denis Toikka");
		netOut.println("Enter HELP for list of commands\n");
		netOut.println("You are located in " + this.game.maze.name + ":");
		netOut.println("  _ _ _ _ ");
		netOut.println("1|_  |   |");
		netOut.println("2|_ _  |_|");
		netOut.println("3|       |");
		netOut.println("4|x|_|_|_|");
		netOut.println("  A B C D ");
		netOut.println("Entry (you are located now): A4");
		netOut.println("Exits: A2, D4");
		netOut.println("Teleports: A1 <---> C4, D2 ---> D3\n");
		netOut.println("Enter NAME <your name>:\n");
	}
	
	/**
	 * @param netOut
	 * Print list of commands.
	 */
	void printHelp(PrintWriter netOut) {
		netOut.println("\nNAME <name> - add player name");
		netOut.println("QUIT - exit from server");
		netOut.println("LOOK - information about current room");
		netOut.println("STATUS - information about player");
		netOut.println("TAKE <item> - grab an item");
		netOut.println("TAKE ALL - grab all items in the room");
		netOut.println("NORTH, SOUTH, EAST, WEST - change room");
		netOut.println("HOME - teleport to maze entry\n");		
	}
}


